﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;

namespace ConnectionBuilder
{
    public partial class ConnectionSQLServer : UserControl
    {
        #region "Delegate"
        /// <summary>
        /// botão conectar
        /// </summary>
        public delegate void ConnectDelegate(Object sender, EventArgs e);
        /// <summary>
        /// evento: clicar em Connect
        /// </summary>
        public event ConnectDelegate OnConnect;

        /// <summary>
        /// botão cancelar
        /// </summary>
        public delegate void CancelDelegate(Object sender, EventArgs e);
        /// <summary>
        /// evento: clicar em Connect
        /// </summary>
        public event CancelDelegate OnCancel;

        /// <summary>
        /// botão help
        /// </summary>
        public delegate void HelpDelegate();
        /// <summary>
        /// evento: clicar em help
        /// </summary>
        public event HelpDelegate OnHelp;

        /// <summary>
        /// botão help
        /// </summary>
        public delegate void OptionsDelegate();
        /// <summary>
        /// evento: clicar em options
        /// </summary>
        public event OptionsDelegate OnOption;

        /// <summary>
        /// delegações de erros
        /// </summary>
        public delegate void ErrorDelegate(Exception e);
        /// <summary>
        /// erros no componente
        /// </summary>
        public event ErrorDelegate OnError;

        /// <summary>
        /// botão conectar
        /// </summary>
        public delegate void AuthenticationDelegate(Int32 authentication);
        /// <summary>
        /// evento: clicar em Connect
        /// </summary>
        public event AuthenticationDelegate OnChangeAuthentication;
        #endregion

        #region "construtor"
        /// <summary>
        /// contrutor da classe
        /// </summary>
        public ConnectionSQLServer()
        {
            InitializeComponent();
            try
            {
                cboAuthenticationType.SelectedIndex = 0;
                tabSQLServerControl.TabPages.Remove(tabPropriedades);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        #endregion

        #region "cboAuthenticationType_TextChanged"
        /// <summary>
        /// change text by authentication
        /// </summary>
        private void cboAuthenticationType_TextChanged(object sender, EventArgs e)
        {
            try
            {
                lblSQLUser.Enabled = (cboAuthenticationType.SelectedIndex != 0);
                lblSQLPassword.Enabled = lblSQLUser.Enabled;
                txtUser.Enabled = lblSQLUser.Enabled;
                txtPassword.Enabled = lblSQLUser.Enabled;
                chkRemember.Enabled = lblSQLUser.Enabled;
                if (!lblSQLUser.Enabled)
                {
                    txtUser.Text = System.Security.Principal.WindowsIdentity.GetCurrent().Name; //  domain\user
                    //txtSQLUser.Text = String.Concat(Environment.UserDomainName, @"\", Environment.UserName); 
                }
                else
                {
                    txtUser.Text = Environment.UserName;
                }

                if (OnChangeAuthentication != null)
                    OnChangeAuthentication(cboAuthenticationType.SelectedIndex);
            }
            catch (Exception ex)
            {
                if (OnError != null)
                    OnError(ex);
                else
                    MessageBox.Show(ex.Message, "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        #endregion

        #region "delegates para os botões"
        /// <summary>
        /// botão connet
        /// </summary>
        private void cmdConnect_Click(Object sender, EventArgs e)
        {
            if (OnConnect != null)
                OnConnect(sender, e);
        }

        /// <summary>
        /// botão cancel
        /// </summary>
        private void cmdCancel_Click(object sender, EventArgs e)
        {
            if (OnCancel != null)
                OnCancel(sender, e);
        }

        /// <summary>
        /// botão help
        /// </summary>
        private void cmdHelp_Click(object sender, EventArgs e)
        {
            if (OnHelp != null)
                OnHelp();
        }

        /// <summary>
        /// botão options
        /// </summary>
        private void cmdOptions_Click(object sender, EventArgs e)
        {
            try
            {
                if (cmdOptions.Text.Substring(cmdOptions.Text.Length - 2) == ">>")
                {
                    cmdOptions.Text = cmdOptions.Text.Substring(0, cmdOptions.Text.Length - 2) + "<<";
                    tabSQLServerControl.TabPages.Add(tabPropriedades);
                    tabSQLServerControl.SelectTab(tabPropriedades);
                }
                else
                {
                    cmdOptions.Text = cmdOptions.Text.Substring(0, cmdOptions.Text.Length - 2) + ">>";
                    tabSQLServerControl.TabPages.Remove(tabPropriedades);
                }
                if (OnOption != null)
                    OnOption();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        #endregion

        #region "Gets do componente"
        /// <summary>
        /// get server name
        /// </summary>
        /// <returns>String</returns>
        public String GetServerName()
        {
            return cboServerName.Text.ToLower();
        }
        /// <summary>
        /// get authentication type
        /// </summary>
        /// <returns>Int32</returns>
        public Int32 GetAuthenticationType()
        {
            return cboAuthenticationType.SelectedIndex;
        }
        /// <summary>
        /// get user name
        /// </summary>
        /// <returns>String</returns>
        public String GetUserName()
        {
            return txtUser.Text;
        }
        /// <summary>
        /// get password
        /// </summary>
        /// <returns>String</returns>
        public String GetPassword()
        {
            return password.Encrypt(txtPassword.Text, "SQLSERVERBuilder");
        }
        /// <summary>
        /// get remember connection
        /// </summary>
        /// <returns>Boolean</returns>
        public Boolean GetRememberIt()
        {
            return chkRemember.Checked;
        }
        /// <summary>
        /// get default database
        /// </summary>
        /// <returns>String</returns>
        public String GetDefaultDatabase()
        {
            return cboDatabaseDefault.Text.ToLower() == "<default>" ? "master" : cboDatabaseDefault.Text;
        }
        /// <summary>
        /// get packet size
        /// </summary>
        /// <returns>Int32</returns>
        public Int32 GetPacketSize()
        {
            return Convert.ToInt32(UDPacket.Value);
        }
        /// <summary>
        /// get connection time-out 
        /// </summary>
        /// <returns>Int32</returns>
        public Int32 GetConnectionTimeOut()
        {
            return Convert.ToInt32(UPConnectionTimeOut.Value);
        }
        /// <summary>
        /// get execution time-out 
        /// </summary>
        /// <returns>Int32</returns>
        public Int32 GetExecutionTimeOut()
        {
            return Convert.ToInt32(UPExecutionTimeOut.Value);
        }
        /// <summary>
        /// get encrypt connection
        /// </summary>
        /// <returns>Boolean</returns>
        public Boolean GetEncryptConnection()
        {
            return chkConnectionEncrypt.Checked;
        }
        #endregion

        #region "Sets componentes"
        /// <summary>
        /// populate last servers connected
        /// </summary>
        /// <param name="servers">String[] "|"</param>
        public void SetServerNames(String[] servers)
        {
            try
            {
                cboServerName.Items.Clear();
                foreach (String s in servers)
                {
                    cboServerName.Items.Add(s);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// populate user name
        /// </summary>
        /// <param name="user">user name</param>
        public void SetUserName(String user)
        {
            txtUser.Text = user;
        }

        /// <summary>
        /// populate password
        /// </summary>
        /// <param name="pwd">password</param>
        public void SetPassword(String pwd)
        {
            txtPassword.Text = password.Decrypt(pwd, "SQLSERVERBuilder");
        }

        /// <summary>
        /// populate rememberit
        /// </summary>
        /// <param name="value"></param>
        public void SetRememberIt(Boolean value)
        {
            chkRemember.Checked = value;
        }
        #endregion

        #region "propriedades da conexão"
        /// <summary>
        /// reseta com as configurações originais
        /// </summary>
        private void cmdResetAll_Click(object sender, EventArgs e)
        {
            try
            {
                cboDatabaseDefault.Enabled = true;
                cboDatabaseDefault.Text = cboDatabaseDefault.Items[0].ToString();
                UDPacket.Value = 4096;
                UPConnectionTimeOut.Value = 15;
                UPExecutionTimeOut.Value = 0;
                chkConnectionEncrypt.Checked = false;
                lstBancos.Visible = false;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// localiza os databases disponíveis na instancia
        /// </summary>
        private void cboDatabaseDefault_SelectedIndexChanged(object sender, EventArgs e)
        {
            SqlConnection cnn = null;
            SqlCommand cmd = null;
            SqlDataReader dr = null;
            try
            {
                if (cboDatabaseDefault.SelectedIndex == 1)
                {
                    if (MessageBox.Show("Para apresentar os bancos de dados será necessário conectar na instância .\nConfirma a conexão?", "Conectar",
                        MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.No)
                        return;

                    if (cboServerName.Text.Trim() == "")
                    {
                        tabSQLServerControl.SelectTab(tabLogin);
                        cboServerName.Focus();
                        throw new Exception("Informe o servidor do banco de dados");
                    }

                    //windows authentication
                    if (cboAuthenticationType.SelectedIndex == 0)
                        cnn = new SqlConnection(String.Format("Data Source={0};Connection Timeout={1};Initial Catalog=master;Integrated Security=SSPI;Persist Security Info=False;",
                            cboServerName.Text, UPConnectionTimeOut.Value));
                    else
                    {
                        if (txtUser.Text.Trim() == "" || txtPassword.Text.Trim() == "")
                            throw new Exception("Informe as credenciais para logar...");

                        cnn = new SqlConnection(String.Format("Data Source={0};Connection Timeout={1};Initial Catalog={2};User ID={3};Password={4};Persist Security Info=True;",
                            cboServerName.Text, UPConnectionTimeOut.Value, "master", txtUser.Text, txtPassword.Text));
                    }

                    cnn.Open();
                    if (cnn.State == ConnectionState.Open)
                    {
                        cmd = new SqlCommand("select name from sys.sysdatabases order by name", cnn);
                        cmd.CommandTimeout = Convert.ToInt32(UPExecutionTimeOut.Value);
                        dr = cmd.ExecuteReader();
                        cmd.Dispose();
                        lstBancos.Items.Clear();
                        lstBancos.Items.Add(cboDatabaseDefault.Items[0].ToString());

                        while (dr.Read())
                            lstBancos.Items.Add(dr["name"].ToString());
                    }
                    else
                        throw new Exception("Erro ao conectar ao banco de dados...");

                    cboDatabaseDefault.Enabled = false;

                    //ListBox position
                    lstBancos.Top = 28;
                    lstBancos.Left = 137;
                    lstBancos.Width = 238;
                    lstBancos.Height = 85;

                    lstBancos.Visible = true;
                }
            }
            catch (SqlException exSQL)
            {
                MessageBox.Show(exSQL.Message, "Error: " + exSQL.ErrorCode.ToString(), MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                if (dr != null && !dr.IsClosed)
                    dr.Close();
                if (cnn != null)
                {
                    if (cnn.State == ConnectionState.Open)
                    {
                        cnn.Close();
                        SqlConnection.ClearPool(cnn);
                    }
                    cnn.Dispose();
                }
                cboDatabaseDefault.SelectedIndex = 0;
            }
        }

        /// <summary>
        /// seleciona um database
        /// </summary>
        private void lstBancos_DoubleClick(object sender, EventArgs e)
        {
            try
            {
                cboDatabaseDefault.Text = lstBancos.Text;
                lstBancos.Visible = false;
                cboDatabaseDefault.Enabled = true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        #endregion

    }
}